diff --git a/board/mousse/flash.c b/board/mousse/flash.c
new file mode 100644
index 0000000..3c4a802
--- /dev/null
+++ b/board/mousse/flash.c
@@ -0,0 +1,944 @@
+/*
+ * MOUSSE/MPC8240 Board definitions.
+ * Flash Routines for MOUSSE onboard AMD29LV106DB devices
+ *
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
+ * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <malloc.h>
+#include "mousse.h"
+#include "flash.h"
+
+int flashLibDebug = 0;
+int flashLibInited = 0;
+
+#define OK  0
+#define ERROR -1
+#define STATUS int
+#define PRINTF			if (flashLibDebug) printf
+#if 0
+#define PRIVATE			static
+#else
+#define PRIVATE
+#endif
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+#define SLEEP_DELAY    166
+#define FLASH_SECTOR_SIZE   (64*1024)
+/***********************************************************************
+ *
+ * Virtual Flash Devices on Mousse board
+ *
+ * These must be kept in sync with the definitions in flashLib.h.
+ *
+ ***********************************************************************/
+
+PRIVATE flash_dev_t flashDev[] = {
+    /* Bank 0 sector SA0 (16 kB) */
+    {	"SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+    /* Bank 0 sector SA1 (8 kB) */
+    {	"SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+    /* Bank 0 sector SA2 (8 kB) */
+    {	"SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+    /* Bank 0 sector SA3 is occluded by Mousse I/O devices */
+    /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB)  */
+    {	"KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+    /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
+    /* This is where the Kahlua boot vector and boot ROM code resides. */
+    {	"BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+    /* Bank 0 sectors SA27-SA34 (512 kB) */
+    {	"RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
+	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+    },
+};
+
+int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
+
+#define DEV(no)			(&flashDev[no])
+#define DEV_NO(dev)		((dev) - flashDev)
+
+/***********************************************************************
+ *
+ * Private Flash Routines
+ *
+ ***********************************************************************/
+
+/*
+ * The convention is:
+ *
+ * "addr" is always the PROM raw address, which is the address of an
+ * 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
+ *
+ * "pos" is always a logical byte position from the PROM beginning.
+ */
+
+#define FLASH0_ADDR(dev, addr) \
+	((unsigned char *) ((dev)->base + (addr)))
+
+#define FLASH0_WRITE(dev, addr, value) \
+	(*FLASH0_ADDR(dev, addr) = (value))
+
+#define FLASH0_READ(dev, addr) \
+	(*FLASH0_ADDR(dev, addr))
+
+PRIVATE int flashCheck(flash_dev_t *dev)
+{
+    if (! flashLibInited) {
+	printf("flashCheck: flashLib not initialized\n");
+	return ERROR;
+    }
+
+    if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
+	printf("flashCheck: Bad dev parameter\n");
+	return ERROR;
+    }
+
+    if (! dev->found) {
+	printf("flashCheck: Device %d not available\n", DEV_NO(dev));
+	return ERROR;
+    }
+
+    return OK;
+}
+
+PRIVATE void flashReset(flash_dev_t *dev)
+{
+    PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
+
+    if (dev->bank == FLASH0_BANK) {
+	FLASH0_WRITE(dev, 0x555, 0xaa);
+	FLASH0_WRITE(dev, 0xaaa, 0x55);
+	FLASH0_WRITE(dev, 0x555, 0xf0);
+    }
+
+    udelay(SLEEP_DELAY);
+
+    PRINTF("flashReset: done\n");
+}
+
+PRIVATE int flashProbe(flash_dev_t *dev)
+{
+    int			rv, deviceID, vendorID;
+
+    PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
+
+    if (dev->bank != FLASH0_BANK) {
+    	rv = ERROR;
+	goto DONE;
+    }
+
+    FLASH0_WRITE(dev, 0xaaa, 0xaa);
+    FLASH0_WRITE(dev, 0x555, 0x55);
+    FLASH0_WRITE(dev, 0xaaa, 0x90);
+
+    udelay(SLEEP_DELAY);
+
+    vendorID = FLASH0_READ(dev, 0);
+    deviceID = FLASH0_READ(dev, 2);
+
+    FLASH0_WRITE(dev, 0, 0xf0);
+
+    PRINTF("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
+
+    if (vendorID == dev->vendorID && deviceID == dev->deviceID)
+	rv = OK;
+    else
+	rv = ERROR;
+
+DONE:
+    PRINTF("flashProbe: rv=%d\n", rv);
+
+    return rv;
+}
+
+PRIVATE int flashWait(flash_dev_t *dev, int addr, int expect, int erase)
+{
+    int			rv = ERROR;
+    int			i, data;
+    int			polls;
+#if 0
+    PRINTF("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
+	   DEV_NO(dev), addr, expect, erase);
+#endif
+
+    if (dev->bank != FLASH0_BANK) {
+	rv = ERROR;
+	goto done;
+    }
+
+    if (erase)
+	polls = FLASH_ERASE_SECTOR_TIMEOUT;	/* Ticks */
+    else
+	polls = FLASH_PROGRAM_POLLS;		/* Loops */
+
+    for (i = 0; i < polls; i++) {
+	if (erase)
+	    udelay(SLEEP_DELAY);
+
+	data = FLASH0_READ(dev, addr);
+
+	if (((data ^ expect) & 0x80) == 0) {
+	    rv = OK;
+	    goto done;
+	}
+
+	if (data & 0x20) {
+	    /*
+	     * If the 0x20 bit has come on, it could actually be because
+	     * the operation succeeded, so check the done bit again.
+	     */
+
+	    data = FLASH0_READ(dev, addr);
+
+	    if (((data ^ expect) & 0x80) == 0) {
+		rv = OK;
+		goto done;
+	    }
+
+	    printf("flashWait: Program error (dev: %d, addr: 0x%x)\n",
+		   DEV_NO(dev), addr);
+
+	    flashReset(dev);
+	    rv = ERROR;
+	    goto done;
+	}
+    }
+
+    printf("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
+	   erase ? "erasing sector" : "programming byte",
+	   DEV_NO(dev), addr);
+
+done:
+
+#if 0
+    PRINTF("flashWait: rv=%d\n", rv);
+#endif
+
+    return rv;
+}
+
+/***********************************************************************
+ *
+ * Public Flash Routines
+ *
+ ***********************************************************************/
+
+STATUS flashLibInit(void)
+{
+    int			i;
+
+    PRINTF("flashLibInit: devices=%d\n", flashDevCount);
+
+    for (i = 0; i < flashDevCount; i++) {
+	flash_dev_t	*dev = &flashDev[i];
+	/*
+	 * For bank 1, probe both without and with byte swappage,
+	 * so that this module works on both old and new Mousse boards.
+	 */
+
+	flashReset(dev);
+
+	if (flashProbe(dev) != ERROR)
+	    dev->found = 1;
+
+	    flashReset(dev);
+
+	    if (flashProbe(dev) != ERROR)
+		dev->found = 1;
+
+	    dev->swap = 0;
+
+	    if(dev->found){
+	      PRINTF("\n  FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
+		     flashDev[i].name,i,flashDev[i].base, flashDev[i].sectors,
+		     (flashDev[i].sectors * FLASH_SECTOR_SIZE)/1024);
+
+	    }
+    }
+
+    flashLibInited = 1;
+
+    PRINTF("flashLibInit: done\n");
+
+    return OK;
+}
+
+STATUS flashEraseSector(flash_dev_t *dev, int sector)
+{
+    int			pos, addr;
+
+    PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
+
+    if (flashCheck(dev) == ERROR)
+	return ERROR;
+
+    if (sector < 0 || sector >= dev->sectors) {
+	printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
+	       DEV_NO(dev), sector);
+	return ERROR;
+    }
+
+    pos = FLASH_SECTOR_POS(dev, sector);
+
+    if (dev->bank != FLASH0_BANK) {
+	return ERROR;
+    }
+
+    addr = pos;
+
+    FLASH0_WRITE(dev, 0xaaa, 0xaa);
+    FLASH0_WRITE(dev, 0x555, 0x55);
+    FLASH0_WRITE(dev, 0xaaa, 0x80);
+    FLASH0_WRITE(dev, 0xaaa, 0xaa);
+    FLASH0_WRITE(dev, 0x555, 0x55);
+    FLASH0_WRITE(dev, addr, 0x30);
+
+    return flashWait(dev, addr, 0xff, 1);
+}
+
+/*
+ * Note: it takes about as long to flash all sectors together with Chip
+ * Erase as it does to flash them one at a time (about 30 seconds for 2
+ * MB).  Also since we want to be able to treat subsets of sectors as if
+ * they were complete devices, we don't use Chip Erase.
+ */
+
+STATUS flashErase(flash_dev_t *dev)
+{
+    int			sector;
+
+    PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
+
+    if (flashCheck(dev) == ERROR)
+	return ERROR;
+
+    for (sector = 0; sector < dev->sectors; sector++) {
+      if (flashEraseSector(dev, sector) == ERROR)
+	    return ERROR;
+    }
+    return OK;
+}
+
+/*
+ * Read and write bytes
+ */
+
+STATUS flashRead(flash_dev_t *dev, int pos, char *buf, int len)
+{
+    int			addr, words;
+
+    PRINTF("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
+	   DEV_NO(dev), pos, (int) buf, len);
+
+    if (flashCheck(dev) == ERROR)
+	return ERROR;
+
+    if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
+	printf("flashRead: Position out of range "
+	       "(dev: %d, pos: 0x%x, len: 0x%x)\n",
+	       DEV_NO(dev), pos, len);
+	return ERROR;
+    }
+
+    if (len == 0)
+	return OK;
+
+    if (dev->bank == FLASH0_BANK) {
+	addr = pos;
+	words = len;
+
+	PRINTF("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
+	       (int) buf, (int) FLASH0_ADDR(dev, pos), len);
+
+	memcpy(buf, FLASH0_ADDR(dev, addr), words);
+
+    }
+    PRINTF("flashRead: rv=OK\n");
+
+    return OK;
+}
+
+STATUS flashWrite(flash_dev_t *dev, int pos, char *buf, int len)
+{
+    int 		addr, words;
+
+    PRINTF("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
+	   DEV_NO(dev), pos, (int) buf, len);
+
+    if (flashCheck(dev) == ERROR)
+	return ERROR;
+
+    if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
+	printf("flashWrite: Position out of range "
+	       "(dev: %d, pos: 0x%x, len: 0x%x)\n",
+	       DEV_NO(dev), pos, len);
+	return ERROR;
+    }
+
+    if (len == 0)
+	return OK;
+
+    if (dev->bank == FLASH0_BANK) {
+	unsigned char tmp;
+
+	addr = pos;
+	words = len;
+
+	while (words--) {
+	    tmp = *buf;
+	    if (~FLASH0_READ(dev, addr) & tmp) {
+		printf("flashWrite: Attempt to program 0 to 1 "
+		       "(dev: %d, addr: 0x%x, data: 0x%x)\n",
+		       DEV_NO(dev), addr, tmp);
+		return ERROR;
+	    }
+	    FLASH0_WRITE(dev, 0xaaa, 0xaa);
+	    FLASH0_WRITE(dev, 0x555, 0x55);
+	    FLASH0_WRITE(dev, 0xaaa, 0xa0);
+	    FLASH0_WRITE(dev, addr, tmp);
+	    if (flashWait(dev, addr, tmp, 0) < 0)
+		return ERROR;
+	    buf++;
+	    addr++;
+	}
+    }
+
+    PRINTF("flashWrite: rv=OK\n");
+
+    return OK;
+}
+
+/*
+ * flashWritable returns TRUE if a range contains all F's.
+ */
+
+STATUS flashWritable(flash_dev_t *dev, int pos, int len)
+{
+    int 		addr, words;
+    int			rv = ERROR;
+
+    PRINTF("flashWritable: dev=%d pos=0x%x len=0x%x\n",
+	   DEV_NO(dev), pos, len);
+
+    if (flashCheck(dev) == ERROR)
+	goto done;
+
+    if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS(dev)) {
+	printf("flashWritable: Position out of range "
+	       "(dev: %d, pos: 0x%x, len: 0x%x)\n",
+	       DEV_NO(dev), pos, len);
+	goto done;
+    }
+
+    if (len == 0) {
+	rv = 1;
+	goto done;
+    }
+
+    if (dev->bank == FLASH0_BANK) {
+	addr = pos;
+	words = len;
+
+	while (words--) {
+	    if (FLASH0_READ(dev, addr) != 0xff) {
+		rv = 0;
+		goto done;
+	    }
+	    addr++;
+	}
+    }
+
+    rv = 1;
+
+ done:
+    PRINTF("flashWrite: rv=%d\n", rv);
+    return rv;
+}
+
+
+/*
+ * NOTE: the below code cannot run from FLASH!!!
+ */
+/***********************************************************************
+ *
+ * Flash Diagnostics
+ *
+ ***********************************************************************/
+
+STATUS flashDiag(flash_dev_t *dev)
+{
+    unsigned int	*buf = 0;
+    int			i, len, sector;
+    int			rv = ERROR;
+
+    if (flashCheck(dev) == ERROR)
+	return ERROR;
+
+    printf("flashDiag: Testing device %d, "
+	   "base: 0x%x, %d sectors @ %d kB = %d kB\n",
+	   DEV_NO(dev), dev->base,
+	   dev->sectors,
+	   1 << (dev->lgSectorSize - 10),
+	   dev->sectors << (dev->lgSectorSize - 10));
+
+    len = 1 << dev->lgSectorSize;
+
+    printf("flashDiag: Erasing\n");
+
+    if (flashErase(dev) == ERROR) {
+	printf("flashDiag: Erase failed\n");
+	goto done;
+    }
+    printf("%d bytes requested ...\n", len);
+    buf = malloc(len);
+    printf("allocated %d bytes ...\n", len);
+    if (buf == 0) {
+	printf("flashDiag: Out of memory\n");
+	goto done;
+    }
+
+    /*
+     * Write unique counting pattern to each sector
+     */
+
+    for (sector = 0; sector < dev->sectors; sector++) {
+	printf("flashDiag: Write sector %d\n", sector);
+
+	for (i = 0; i < len / 4; i++)
+	    buf[i] = sector << 24 | i;
+
+	if (flashWrite(dev,
+		       sector << dev->lgSectorSize,
+		       (char *) buf,
+		       len) == ERROR) {
+	    printf("flashDiag: Write failed (dev: %d, sector: %d)\n",
+		   DEV_NO(dev), sector);
+	    goto done;
+	}
+    }
+
+    /*
+     * Verify
+     */
+
+    for (sector = 0; sector < dev->sectors; sector++) {
+	printf("flashDiag: Verify sector %d\n", sector);
+
+	if (flashRead(dev,
+		      sector << dev->lgSectorSize,
+		      (char *) buf,
+		      len) == ERROR) {
+	    printf("flashDiag: Read failed (dev: %d, sector: %d)\n",
+		   DEV_NO(dev), sector);
+	    goto done;
+	}
+
+	for (i = 0; i < len / 4; i++) {
+	    if (buf[i] != (sector << 24 | i)) {
+		printf("flashDiag: Verify error "
+		       "(dev: %d, sector: %d, offset: 0x%x)\n",
+		       DEV_NO(dev), sector, i);
+		printf("flashDiag: Expected 0x%08x, got 0x%08x\n",
+		       sector << 24 | i, buf[i]);
+
+		goto done;
+	    }
+	}
+    }
+
+    printf("flashDiag: Erasing\n");
+
+    if (flashErase(dev) == ERROR) {
+	printf("flashDiag: Final erase failed\n");
+	goto done;
+    }
+
+    rv = OK;
+
+ done:
+    if (buf)
+	free(buf);
+
+    if (rv == OK)
+	printf("flashDiag: Device %d passed\n", DEV_NO(dev));
+    else
+	printf("flashDiag: Device %d failed\n", DEV_NO(dev));
+
+    return rv;
+}
+
+STATUS flashDiagAll(void)
+{
+    int			i;
+    int			rv = OK;
+
+    PRINTF("flashDiagAll: devices=%d\n", flashDevCount);
+
+    for (i = 0; i < flashDevCount; i++) {
+	flash_dev_t	*dev = &flashDev[i];
+
+	if (dev->found && flashDiag(dev) == ERROR)
+	    rv = ERROR;
+    }
+
+    if (rv == OK)
+	printf("flashDiagAll: Passed\n");
+    else
+	printf("flashDiagAll: Failed because of earlier errors\n");
+
+    return OK;
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+unsigned long flash_init (void)
+{
+    unsigned long size = 0;
+    flash_dev_t	*dev = NULL;
+    flashLibInit();
+
+    /*
+     * Provide info for FLASH (up to 960K) of Kernel Image data.
+     */
+    dev = FLASH_DEV_BANK0_LOW;
+    flash_info[FLASH_BANK_KERNEL].flash_id =
+      (dev->vendorID << 16) | dev->deviceID;
+    flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
+    flash_info[FLASH_BANK_KERNEL].size =
+      flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
+    flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
+    size += flash_info[FLASH_BANK_KERNEL].size;
+
+    /*
+     * Provide info for 512K PLCC FLASH ROM (U-Boot)
+     */
+    dev = FLASH_DEV_BANK0_BOOT;
+    flash_info[FLASH_BANK_BOOT].flash_id =
+      (dev->vendorID << 16) | dev->deviceID;
+    flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
+    flash_info[FLASH_BANK_BOOT].size =
+      flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
+    flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
+    size += flash_info[FLASH_BANK_BOOT].size;
+
+
+    /*
+     * Provide info for 512K FLASH0 segment (U-Boot)
+     */
+    dev = FLASH_DEV_BANK0_HIGH;
+    flash_info[FLASH_BANK_AUX].flash_id =
+      (dev->vendorID << 16) | dev->deviceID;
+    flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
+    flash_info[FLASH_BANK_AUX].size =
+      flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
+    flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
+    size += flash_info[FLASH_BANK_AUX].size;
+
+
+    return  size;
+}
+
+/*
+ * Get flash device from U-Boot flash info.
+ */
+flash_dev_t*
+getFlashDevFromInfo(flash_info_t* info)
+{
+  int i;
+
+  if(!info)
+    return NULL;
+
+  for (i = 0; i < flashDevCount; i++) {
+    flash_dev_t	*dev = &flashDev[i];
+    if(dev->found && (dev->base == info->start[0]))
+      return dev;
+  }
+  printf("ERROR: notice, no FLASH mapped at address 0x%x\n",
+	 (unsigned int)info->start[0]);
+  return NULL;
+}
+
+ulong
+flash_get_size (vu_long *addr, flash_info_t *info)
+{
+    int i;
+    for(i = 0; i < flashDevCount; i++) {
+      flash_dev_t	*dev = &flashDev[i];
+      if(dev->found){
+	if(dev->base == (unsigned int)addr){
+	  info->flash_id = (dev->vendorID << 16) | dev->deviceID;
+	  info->sector_count = dev->sectors;
+	  info->size = info->sector_count * FLASH_SECTOR_SIZE;
+	  return dev->sectors * FLASH_SECTOR_SIZE;
+	}
+      }
+    }
+    return 0;
+}
+
+void
+flash_print_info  (flash_info_t *info)
+{
+  int i;
+  unsigned int chip;
+
+    if (info->flash_id == FLASH_UNKNOWN) {
+	printf ("missing or unknown FLASH type\n");
+	return;
+    }
+
+    switch ((info->flash_id >> 16) & 0xff) {
+    case 0x1:
+	printf ("AMD ");
+	break;
+    default:
+	printf ("Unknown Vendor ");
+	break;
+    }
+    chip = (unsigned int) info->flash_id & 0x000000ff;
+
+    switch (chip) {
+
+    case AMD_ID_F040B:
+	printf ("AM29F040B (4 Mbit)\n");
+	break;
+
+    case AMD_ID_LV160B:
+    case FLASH_AM160LV:
+    case 0x49:
+	printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
+	break;
+
+    default:
+      printf ("Unknown Chip Type:0x%x\n", chip);
+	break;
+    }
+
+    printf ("  Size: %ld bytes in %d Sectors\n",
+	    info->size, info->sector_count);
+
+    printf ("  Sector Start Addresses:");
+    for (i=0; i<info->sector_count; ++i) {
+      if ((i % 5) == 0)
+	  printf ("\n   ");
+	printf (" %08lX%s",
+		info->start[FIRST_SECTOR] + i*FLASH_SECTOR_SIZE,
+		info->protect[i] ? " (RO)" : "     "
+		);
+    }
+    printf ("\n");
+}
+
+
+/*
+ * Erase a range of flash sectors.
+ */
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    vu_long *addr = (vu_long*)(info->start[0]);
+    int prot, sect, l_sect;
+    flash_dev_t* dev = NULL;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+	if (info->flash_id == FLASH_UNKNOWN) {
+	    printf ("- missing\n");
+	} else {
+	    printf ("- no sectors to erase\n");
+	}
+	return 1;
+    }
+
+    prot = 0;
+    for (sect = s_first; sect <= s_last; sect++) {
+	if (info->protect[sect]) {
+	    prot++;
+	}
+    }
+
+    if (prot) {
+	printf ("- Warning: %d protected sectors will not be erased!\n",
+		prot);
+    } else {
+	printf ("\n");
+    }
+
+    l_sect = -1;
+
+    /* Start erase on unprotected sectors */
+    dev = getFlashDevFromInfo(info);
+    if(dev){
+      printf("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
+      for (sect = s_first; sect<=s_last; sect++) {
+	if (info->protect[sect] == 0) {	/* not protected */
+	  addr = (vu_long*)(dev->base);
+	  /*   printf("erase_sector: sector=%d, addr=0x%x\n",
+	       sect, addr); */
+	  printf(".");
+	  if(ERROR == flashEraseSector(dev, sect)){
+	    printf("ERROR: could not erase sector %d on FLASH[%s]\n",
+		   sect, dev->name);
+	    return 1;
+	  }
+	}
+      }
+    }
+    printf (" done\n");
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int
+write_word (flash_info_t *info, ulong dest, ulong data)
+{
+
+  flash_dev_t* dev = getFlashDevFromInfo(info);
+  int addr = dest - info->start[0];
+
+  if (! dev)
+    return 1;
+
+  if(OK != flashWrite(dev, addr, (char*)&data, sizeof(ulong))){
+    printf("ERROR: could not write to addr=0x%x, data=0x%x\n",
+	   (unsigned int)addr, (unsigned)data);
+    return 1;
+  }
+
+  if((addr % FLASH_SECTOR_SIZE) == 0)
+    printf(".");
+
+
+  PRINTF("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
+	 (unsigned)info->start[0],
+	 (unsigned)dest,
+	 (unsigned)(dest - info->start[0]),
+	 (unsigned)data);
+
+
+
+    return (0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    int i, l, rc;
+    flash_dev_t* dev = getFlashDevFromInfo(info);
+
+    if( dev ) {
+      printf("FLASH[%s]:", dev->name);
+      wp = (addr & ~3);	/* get lower word aligned address */
+
+      /*
+       * handle unaligned start bytes
+       */
+      if ((l = addr - wp) != 0) {
+	data = 0;
+	for (i=0, cp=wp; i<l; ++i, ++cp) {
+	  data = (data << 8) | (*(uchar *)cp);
+	}
+	for (; i<4 && cnt>0; ++i) {
+	  data = (data << 8) | *src++;
+	  --cnt;
+	  ++cp;
+	}
+	for (; cnt==0 && i<4; ++i, ++cp) {
+	  data = (data << 8) | (*(uchar *)cp);
+	}
+	if ((rc = write_word(info, wp, data)) != 0) {
+	  return (rc);
+	}
+	wp += 4;
+      }
+
+      /*
+       * handle word aligned part
+       */
+      while (cnt >= 4) {
+	data = 0;
+	for (i=0; i<4; ++i) {
+	  data = (data << 8) | *src++;
+	}
+	if ((rc = write_word(info, wp, data)) != 0) {
+	  return (rc);
+	}
+	wp  += 4;
+	cnt -= 4;
+      }
+
+      if (cnt == 0) {
+	return (0);
+      }
+
+      /*
+       * handle unaligned tail bytes
+       */
+      data = 0;
+      for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+	data = (data << 8) | *src++;
+	--cnt;
+      }
+      for (; i<4; ++i, ++cp) {
+	data = (data << 8) | (*(uchar *)cp);
+      }
+
+      return (write_word(info, wp, data));
+    }
+    return 1;
+}
+
+/*-----------------------------------------------------------------------
+ */
